---
title: What is a machine?
description: A brief explanation of the state machine concept
---

A state machine is a tool for modeling stateful, reactive systems. It is useful
for declaratively describing the behavior of an application or component.

To model any logic as using the state machine pattern, it must have:

- A finite number of states.
- A finite number of transitions between states.

## Creating a state machine

Consider a simple toggle or switch component that consists of two states,
`active` and `inactive`. The initial state will be `active`

The supported transitions that can happen here:

- In the `active` state, when we click the toggle, it should transition to the
  `inactive` state
- In the `inactive` state, when we click the toggle, it should transition to the
  `active` state

Here's how we'll model the logic in code:

```jsx
import { createMachine } from "@zag-js/core"

const machine = createMachine({
  // initial state
  initialState() {
    return "active"
  },
  // the finite states
  states: {
    active: {
      on: {
        CLICK: {
          // go to inactive
          target: "inactive",
        },
      },
    },
    inactive: {
      on: {
        CLICK: {
          // go to active
          target: "active",
        },
      },
    },
  },
})
```

### TypeScript Guide

For TypeScript projects, you can add type definitions to make your machine
type-safe:

```tsx
import { createMachine, type Service } from "@zag-js/core"
import type { NormalizeProps, PropTypes } from "@zag-js/types"

interface ToggleSchema {
  state: "active" | "inactive"
  event: { type: "CLICK" }
}

export const machine = createMachine<ToggleSchema>({
  // ... same as above
})
```

## Writing the connect function

Now that we've modelled the component logic, let's map that to DOM attributes
and event handlers following the
[WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.1/examples/checkbox/checkbox-1/checkbox-1.html)
specification for the switch component.

We'll write a function called `connect` to do this.

```jsx
function connect(service, normalize) {
  const { state, send } = service
  const active = state.matches("active")
  return {
    active,
    getButtonProps() {
      return normalize.button({
        type: "button",
        role: "switch",
        "aria-checked": active,
        onClick() {
          send({ type: "CLICK" })
        },
      })
    },
  }
}
```

### TypeScript Guide

For TypeScript projects, you can add type definitions to make your connect
function type-safe:

```tsx
import { type Service } from "@zag-js/core"
import type { NormalizeProps, PropTypes } from "@zag-js/types"

interface ToggleSchema {
  state: "active" | "inactive"
  event: { type: "CLICK" }
}

export function connect<T extends PropTypes>(
  service: Service<ToggleSchema>,
  normalize: NormalizeProps<T>,
) {
  const { state, send } = service
  const active = state.matches("active")
  return {
    active,
    getButtonProps() {
      return normalize.button({
        type: "button",
        role: "switch",
        "aria-checked": active,
        onClick() {
          send({ type: "CLICK" })
        },
      })
    },
  }
}
```

## Consuming the state machine

Here's how to consume the toggle machine logic and connect in React.js.

```jsx
import { useMachine, normalizeProps } from "@zag-js/react"
import { machine, connect } from "./toggle"

function Toggle() {
  const service = useMachine(machine)
  const api = connect(service, normalizeProps)

  return (
    <button
      {...api.getButtonProps()}
      style={{
        width: "40px",
        height: "24px",
        borderRadius: "999px",
        background: api.active ? "green" : "gray",
      }}
    >
      {api.active ? "ON" : "OFF"}
    </button>
  )
}
```

That's it! Now you've learned the fundamentals of a component state machine.

## Next Steps

Now that you understand the basics, learn about the advanced concepts that power Zag machines:

- [Building Machines Guide](/guides/building-machines) - Deep dive into context (bindable), watch/track, computed, refs, and more
